package negocio;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;

import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;

import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import beans.MesaVO;
import beans.PedidoVO;


@Entity
@Table(name="mesas")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="tipo", discriminatorType=DiscriminatorType.STRING )


public class Mesa implements Serializable
{
	
	private static final long serialVersionUID = 1L;
	
	@Column(name="cant_personas" , nullable=true)
	protected int cant_personas;
	
	@Column(name="maxCant_Personas", nullable= true)
	protected int maxCant_Personas;
	
	@Id
	@GeneratedValue(strategy=GenerationType.TABLE)
	@Column(name="id_Mesa", nullable=false)
	protected int id_Mesa;
	
	@Column(name="estado", nullable=true)
	protected String estado;
	
	@Column(name="numeroMesa", nullable=false)
	protected int numeroMesa;
	
	@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
	@JoinColumn(name="id_Mesa", referencedColumnName="id_Mesa")
	protected List<Pedido>pedidos= new ArrayList<>();
	
	@Column(name="fecha_de_apertura", nullable=true)
	protected Date fecha_de_apertura;
	
	@Column(name="tiempo_de_Permanencia", nullable=true)
	protected int tiempo_de_Permanencia;
	
	@Column(name="fecha_de_liberacion", nullable=true)
	protected Date fecha_de_liberacion;
	
	
	public int getCant_personas() {
		return cant_personas;
	}
	public void setCant_personas(int cant_personas) {
		this.cant_personas = cant_personas;
	}
	public int getMaxCant_Personas() {
		return maxCant_Personas;
	}
	public void setMaxCant_Personas(int maxCant_Personas) {
		this.maxCant_Personas = maxCant_Personas;
	}
	public int getId_numeroMesas() {
		return id_Mesa;
	}
	public void setId_numeroMesas(int id_numeroMesas) {
		this.id_Mesa = id_numeroMesas;
	}
	public String getEstado() {
		return estado;
	}
	public void setEstado(String estado) {
		this.estado = estado;
	}
	public int getNumeroMesa() {
		return numeroMesa;
	}
	public void setNumeroMesa(int numeroMesa) {
		this.numeroMesa = numeroMesa;
	}
	public List<Pedido> getPedidos() {
		return pedidos;
	}
	public void setPedidos(List<Pedido> pedidos) {
		this.pedidos = pedidos;
	}
	public Date getFecha_de_apertura() {
		return fecha_de_apertura;
	}
	public void setFecha_de_apertura(Date fecha_de_apertura) {
		this.fecha_de_apertura = fecha_de_apertura;
	}
	public int getTiempo_de_Permanencia() {
		return tiempo_de_Permanencia;
	}
	public void setTiempo_de_Permanencia(int tiempo_de_Permanencia) {
		this.tiempo_de_Permanencia = tiempo_de_Permanencia;
	}
	public Date getFecha_de_liberacion() {
		return fecha_de_liberacion;
	}
	public void setFecha_de_liberacion(Date fecha_de_liberacion) {
		this.fecha_de_liberacion = fecha_de_liberacion;
	}
	
	public MesaVO getVO()
	{
		MesaVO mesaVO = new MesaVO();
		mesaVO.setId_numeroMesas(getId_numeroMesas());
		mesaVO.setCant_personas(getCant_personas());
		mesaVO.setEstado(getEstado());
		mesaVO.setFecha_de_apertura(getFecha_de_apertura());
		mesaVO.setFecha_de_liberacion(getFecha_de_apertura());
		mesaVO.setMaxCant_Personas(getMaxCant_Personas());
		mesaVO.setNumeroMesa(getNumeroMesa());
		ArrayList<PedidoVO> pedidosVO = new ArrayList<PedidoVO>();
		for (int i = 0 ; i < getPedidos().size() ; i++)
		{
			PedidoVO pedVO = getPedidos().get(i).getVO();
			pedidosVO.add(pedVO);
		}
		mesaVO.setPedidos(pedidosVO);
		mesaVO.setTiempo_de_Permanencia(getTiempo_de_Permanencia());
		
		return mesaVO;
	}
	
	//toString
	@Override
	public String toString() 
	{
		return "Mesa [cant_personas=" + cant_personas + ", maxCant_Personas="
				+ maxCant_Personas + ", id_numeroMesas=" + id_Mesa
				+ ", estado=" + estado + ", numeroMesa=" + numeroMesa
				+ ", pedidos=" + pedidos + ", fecha_de_apertura="
				+ fecha_de_apertura + ", tiempo_de_Permanencia="
				+ tiempo_de_Permanencia + ", fecha_de_liberacion="
				+ fecha_de_liberacion + "]";
	}
	
	//hashcode and equals
	
	@Override
	public int hashCode() 
	{
		final int prime = 31;
		int result = 1;
		result = prime * result + cant_personas;
		result = prime * result + ((estado == null) ? 0 : estado.hashCode());
		result = prime
				* result
				+ ((fecha_de_apertura == null) ? 0 : fecha_de_apertura
						.hashCode());
		result = prime
				* result
				+ ((fecha_de_liberacion == null) ? 0 : fecha_de_liberacion
						.hashCode());
		result = prime * result + id_Mesa;
		result = prime * result + maxCant_Personas;
		result = prime * result + numeroMesa;
		result = prime * result + ((pedidos == null) ? 0 : pedidos.hashCode());
		result = prime * result + tiempo_de_Permanencia;
		return result;
	}
	@Override
	public boolean equals(Object obj) 
	{
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Mesa other = (Mesa) obj;
		if (cant_personas != other.cant_personas)
			return false;
		if (estado == null) {
			if (other.estado != null)
				return false;
		} else if (!estado.equals(other.estado))
			return false;
		if (fecha_de_apertura == null) {
			if (other.fecha_de_apertura != null)
				return false;
		} else if (!fecha_de_apertura.equals(other.fecha_de_apertura))
			return false;
		if (fecha_de_liberacion == null) {
			if (other.fecha_de_liberacion != null)
				return false;
		} else if (!fecha_de_liberacion.equals(other.fecha_de_liberacion))
			return false;
		if (id_Mesa != other.id_Mesa)
			return false;
		if (maxCant_Personas != other.maxCant_Personas)
			return false;
		if (numeroMesa != other.numeroMesa)
			return false;
		if (pedidos == null) {
			if (other.pedidos != null)
				return false;
		} else if (!pedidos.equals(other.pedidos))
			return false;
		if (tiempo_de_Permanencia != other.tiempo_de_Permanencia)
			return false;
		return true;
	}
	
	public void asignarPedido(Pedido pedido)
	{
		this.pedidos.add(pedido);
	}
	
	public void abrirMesa(int cantPersonas, Date fechaApertura)
	{
		this.cant_personas = cantPersonas;
		this.fecha_de_apertura = fechaApertura;
		this.estado = "Ocupada";
		this.pedidos.clear();
	}
	
	public void cerrarMesa()
	{
		this.estado = "Cerrada";
		this.fecha_de_liberacion = new Date();
		
		/*Tiempo de permanencia - en minutos*/
		this.tiempo_de_Permanencia = (int) 
				((this.fecha_de_liberacion.getTime() - this.fecha_de_apertura.getTime())
				/ (1000 * 60));
	}
	
	public void liberarMesa()
	{
		this.estado = "Libre";
		this.fecha_de_apertura = null;
		this.fecha_de_liberacion = null;
		this.tiempo_de_Permanencia = 0;
		this.pedidos.clear();
	}
	
	public boolean isLibre()
	{
		return this.estado.equals("Libre");
	}
	public void buildFromVO(MesaVO mesaVO) {
		this.estado = "Libre";
		this.fecha_de_apertura = null;
		this.fecha_de_liberacion = null;
		this.tiempo_de_Permanencia = 0;
		this.cant_personas = 0;
		this.numeroMesa = mesaVO.getNumeroMesa();
		this.maxCant_Personas = mesaVO.getMaxCant_Personas();
	}
}
